#  coding=utf-8
# if the python sdk is not install using 'sudo pip install aliyun-python-sdk-ecs'
# if the python sdk is install using 'sudo pip install --upgrade aliyun-python-sdk-ecs'
# make sure the sdk version is 4.4.3, you can use command 'pip show aliyun-python-sdk-ecs' to check

import json
import logging
import time
from aliyunsdkcore import client
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkecs.request.v20140526.RunInstancesRequest import RunInstancesRequest
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                    datefmt='%a, %d %b %Y %H:%M:%S')

# 您的access key Id。
ak_id = "<Accessid>"

# 您的access key secret。
ak_secret = "<AccessSecret>"

# 设置地域。
region_id = "设置地域id"

clt = client.AcsClient(ak_id, ak_secret, region_id)

#设置实例名称
instance_name = "指定实例名(例如simon-ecs-test-20211104)" 

# 设置实例规格。
instance_type = "指定规格(例如ecs.s6-c1m1.small)"

# 选择的交换机。
vswitch_id = "指定交换机例如(vsw-2ze30c*************)"

# 使用的镜像信息。
image_id = "指定镜像(例如centos_8_4_x64_20G_alibase_20210927.vhd)"

# 当前VPC类型的安全组。
security_group_id = "指定安全组(例如sg-2ze75**********)"

# 批量创建ECS实例的数量, 取值范围：1-100, 默认值：1
amount = 2

# 自动释放时间。使用UTC时间，格式为 yyyy-MM-ddTHH:mm:ssZ。最短释放时间为当前时间半小时之后；最长释放时间不能超过当前时间三年
auto_release_time = "2021-11-04T09:40:00Z"

# 创建ECS实例并启动
def create_multiple_instances():
    request = build_request()
    request.set_Amount(amount)
    _execute_request(request)

# 创建ECS实例并分配公网IP
def create_multiple_instances_with_public_ip():
    request = build_request()
    request.set_Amount(amount)
    request.set_InternetMaxBandwidthOut(5)
    _execute_request(request)

# 创建ECS实例并设置自动释放时间
def create_multiple_instances_with_auto_release_time():
    request = build_request()
    request.set_Amount(amount)
    request.set_AutoReleaseTime(auto_release_time)
    _execute_request(request)

#综合批量创建ECS实例
def create_multiple_instances_with_public_ip_and_auto_release_time():
    request = build_request()
    request.set_Amount(amount)
    request.set_InternetMaxBandwidthOut(5)
    request.set_AutoReleaseTime(auto_release_time)
    _execute_request(request)


def _execute_request(request):
    response = _send_request(request)
    if response.get('Code') is None:
        instance_ids = response.get('InstanceIdSets').get('InstanceIdSet')
        running_amount = 0
        while running_amount < amount:
            time.sleep(10)
            running_amount = check_instance_running(instance_ids)
    print("ecs instance %s is running", instance_ids)

def check_instance_running(instance_ids):
    request = DescribeInstancesRequest()
    request.set_InstanceIds(json.dumps(instance_ids))
    response = _send_request(request)
    if response.get('Code') is None:
        instances_list = response.get('Instances').get('Instance')
        running_count = 0
        for instance_detail in instances_list:
            if instance_detail.get('Status') == "Running":
                running_count += 1
        return running_count

def build_request():
    request = RunInstancesRequest()
    request.set_ImageId(image_id)
    request.set_VSwitchId(vswitch_id)
    request.set_SecurityGroupId(security_group_id)
    request.set_InstanceName(instance_name)
    request.set_InstanceType(instance_type)
    # 指定盘类型和系统盘大小，其实不写也行，这些都是默认
    # request.set_SystemDiskCategory("cloud_essd")    #系统盘类型
    # request.set_SystemDiskSize("40")    #系统盘大小
    # 主机名也可以不指定，创建之后手动改
    request.set_HostName("指定你的主机名")  
    # 不指定密码的话可以去控制台自己修改，总感觉把密码设在这里不是很安全
    # request.set_Password("指定实例的密码")
    # 以下可不加，默认就是按量付费，按照你释放的时间取小时计费，所以其实只需设置释放时间即可    
    request.set_InstanceChargeType("PostPaid")   #设置按量付费
    request.set_Period(1)    #购买时长
    request.set_PeriodUnit("Hourly")    #购买资源的时长单位
    return request

# 发送API请求
def _send_request(request):
    request.set_accept_format('json')
    try:
        response_str = clt.do_action(request)
        logging.info(response_str)
        response_detail = json.loads(response_str)
        return response_detail
    except Exception as e:
        logging.error(e)

if __name__ == '__main__':
    print ("hello ecs batch create instance")
    ###########这里有几种模式可以设置##############
    # 1.创建ECS实例并启动。
    # create_multiple_instances()
    # 2.创建绑定公网IP的ECS实例。
    create_multiple_instances_with_public_ip()
    # 3.创建ECS实例并设置自动释放时间。
    # create_multiple_instances_with_auto_release_time()
    # 4.创建绑定公网IP的ECS实例并设置自动释放时间
    # create_multiple_instances_with_public_ip_and_auto_release_time()